package bt.basics.common.utils;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MapUtils {

    /**
     * map转为javabean
     *
     * @param map
     * @param clazz
     * @param <T>
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     */
    public static <T> T parsePoje(Map<String, Object> map, Class<T> clazz) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
        T t = clazz.newInstance();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            JacksonXmlProperty pojoAnnotation = field.getAnnotation(JacksonXmlProperty.class);
            if (pojoAnnotation != null) {
                Object o = map.get(pojoAnnotation.localName());
                if (o != null) {
                    String fieldName = field.getName();
                    Method method = clazz.getMethod("set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1), o.getClass());
                    method.invoke(t, o);
                }
            }
        }
        return t;
    }

    /**
     * javabean转成map
     *
     * @param object
     * @return
     */
    public static Map<String, Object> beanToMap(Object object) {
        Map<String, Object> map = new HashMap<>();
        Class clazz = object.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(JacksonXmlProperty.class)) {
                JacksonXmlProperty pojoAnnotation = field.getAnnotation(JacksonXmlProperty.class);
                String name = pojoAnnotation.localName();
                try {
                    PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                    Method method = pd.getReadMethod();
                    Object value = method.invoke(object);
                    if (value != null) {
                        map.put(name, value);
                    }else{
                        map.put(name, "");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
        return map;
    }

    /**
     * javabean List转 List<Map<String, Object>>
     * @param list
     * @return
     */
    public static List<Map<String, Object>> ListToMap(List<Object> list){
        List<Map<String, Object>> maps = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            maps.add(MapUtils.beanToMap(list.get(i)));
        }
        return maps;
    }

}
